package vampire.com.baidumusic.tools.dbtools;

import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import com.litesuits.orm.LiteOrm;
import com.litesuits.orm.db.assit.QueryBuilder;
import com.litesuits.orm.db.assit.WhereBuilder;
import com.litesuits.orm.db.model.ConflictAlgorithm;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Pattern;

import cn.bmob.v3.BmobObject;
import cn.bmob.v3.BmobUser;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.SaveListener;
import cn.bmob.v3.listener.UpdateListener;
import vampire.com.baidumusic.base.MyApp;

/**
 * Created BaiDuMusic by *Vampire* on 16/8/25.
 */
public class DBTool {

    private static DBTool ourInstance;

    private LiteOrm liteOrm;

    private Handler handler;

    ExecutorService threadPool = Executors.newFixedThreadPool(getNumCores()+1);

    public static DBTool getInstance() {
        if (ourInstance == null) {
            synchronized (DBTool.class) {
                if (ourInstance == null) {
                    ourInstance = new DBTool();
                }
            }
        }
        return ourInstance;
    }

    private DBTool() {
        liteOrm = LiteOrm.newSingleInstance(MyApp.getContext(), "BaiDuBase.db");

        handler = new Handler(Looper.getMainLooper());
    }

    // 储存播放列表;
    public void insertDBMusicList(final DBMusicList dbMusicList) {
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                liteOrm.insert(dbMusicList);
            }
        });
    }

    // 添加我最喜欢的歌单;
    public void insertMyFavoriteList(final DBMyFavoriteList dbMyFavoriteList) {
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                liteOrm.insert(dbMyFavoriteList);
                // 存取网络数据
                DBMyFavoriteList dbMyMusicList1 = BmobUser.getCurrentUser(DBMyFavoriteList.class);
                if (dbMyMusicList1 != null && !BmobUser.getCurrentUser().getUsername().equals("0")) {
                    dbMyFavoriteList.setUsername(dbMyMusicList1.getUsername());
                    if (dbMyFavoriteList==null){
                        return;
                    }
                    dbMyFavoriteList.save(new SaveListener<String>() {
                        @Override
                        public void done(String s, BmobException e) {
                            if (e == null) {
                                Log.d("DBTool", "储存成功");
                            } else {
                                Log.d("DBTool", e + "储存失败");
                            }
                        }
                    });
                } else {
                    Log.d("DBTool", "尚未登录");
                }

            }
        });
    }

    // 重载添加我最喜欢的歌单 , 用于从网络拉取
    public void insertMyFavoriteList(final DBMyFavoriteList dbMyFavoriteList , int temp) {
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                liteOrm.insert(dbMyFavoriteList);

            }
        });
    }

    // 储存最近播放列表
    public void insertDBHistory(final DBHistoryPlay dbHistoryPlay, final String songId) {
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                List<DBHistoryPlay> dbHistoryPlays = liteOrm.query(DBHistoryPlay.class);
                QueryBuilder<DBHistoryPlay> builder = new QueryBuilder<DBHistoryPlay>(DBHistoryPlay.class);
                builder.where("songId = " + songId);
                List<DBHistoryPlay> songIDs = liteOrm.query(builder);
                if (songIDs.size() <= 0) {//去重
                    if (dbHistoryPlays.size() < 30) { // 并控制最近播放的个数为30;
                        liteOrm.insert(dbHistoryPlay);
                    } else {
                        liteOrm.delete(dbHistoryPlays.get(0));
                        // 添最新
                        liteOrm.insert(dbHistoryPlay);

                    }
                }
            }
        });
    }

    // 查询播放列表;
    public void queryDBMusicList(final QueryListener queryListener) {
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                List<DBMusicList> musicLists = liteOrm.query(DBMusicList.class);
                handler.post(new HandlerRunnable(queryListener, musicLists));
            }
        });

    }

    // 查询我收藏的歌单
    public void queryDBMfavorite(final QueryListener queryListener) {
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                List<DBMyFavoriteList> dbMyFavoriteLists = liteOrm.query(DBMyFavoriteList.class);
                handler.post(new HandlerRunnable(queryListener, dbMyFavoriteLists));
            }
        });
    }

    // 查询历史播放;
    public void queryHistory(final QueryListener queryListener) {
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                List<DBHistoryPlay> dbHistoryPlays = liteOrm.query(DBHistoryPlay.class);
                handler.post(new HandlerRunnable(queryListener, dbHistoryPlays));
            }
        });
    }

    // 查询我的收藏列表
    public void queryDBMyMusicList(final QueryListener queryListener) {
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                List<DBMyMusicList> dbMyMusicLists = liteOrm.query(DBMyMusicList.class);
                handler.post(new HandlerRunnable(queryListener, dbMyMusicLists));

            }
        });
    }

    // 数据库;
    public <T> void cleanDBMusicList(final Class<T> clazz) {
        Log.d("DBTool", "清数据库");
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                liteOrm.deleteAll(clazz);
            }
        });
    }

    // 通过SongId删数据库
    public void delDBMyMusicListBySongId(final String songId) {
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                liteOrm.delete(new WhereBuilder(DBMyMusicList.class) // 表名
                        .where("songId = " + songId)// 删除列名 及参数
                        .and()
                        .greaterThan("id", 0)// 最小id
                        .and()
                        .lessThan("id", 100000000));// 最大id
                DBMyMusicList dbMyMusicList = BmobUser.getCurrentUser(DBMyMusicList.class);
                if (dbMyMusicList != null && !BmobUser.getCurrentUser().getUsername().equals("0")) {
                    dbMyMusicList.setUsername(dbMyMusicList.getUsername());
                    if (dbMyMusicList==null){
                        return;
                    }
                    dbMyMusicList.delete(songId, new UpdateListener() {
                        @Override
                        public void done(BmobException e) {
                            if (e==null){
                                Log.d("DBTool", "云删");
                            }else {
                                Log.d("DBTool", "云删失败");
                            }
                        }
                    });
                } else {
                    Log.d("DBTool", "尚未登录");
                }
            }
        });

    }

    // 删除我最喜欢的歌单;
    public void delMyFavoriteList(final String url) {
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                Log.d("DBTool", "删");
                liteOrm.delete(new WhereBuilder(DBMyMusicList.class) // 表名
                        .where("url = " , url)// 删除列名 及参数
                        .and()
                        .greaterThan("id", 0)// 最小id
                        .and()
                        .lessThan("id", 100000000));// 最大id

                DBMyMusicList dbMyMusicList = BmobUser.getCurrentUser(DBMyMusicList.class);
                if (dbMyMusicList != null && !BmobUser.getCurrentUser().getUsername().equals("0")) {
                    dbMyMusicList.setUsername(dbMyMusicList.getUsername());
                    if (dbMyMusicList==null){
                        return;
                    }
                    DBMyFavoriteList dbMyFavoriteList =new DBMyFavoriteList();
                    dbMyFavoriteList.setUrl(url);
                    dbMyMusicList.delete(new UpdateListener() {
                        @Override
                        public void done(BmobException e) {
                            if (e==null){
                                Log.d("DBTool", "云删");
                            }else {
                                Log.d("DBTool", "云删失败");
                            }
                        }
                    });
                } else {
                    Log.d("DBTool", "尚未登录");
                }

            }
        });
    }

    // 通过网址查歌单
    public void queryMyFavoriteList(final String url, final QueryListener queryListener) {
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                QueryBuilder<DBMyFavoriteList> builder = new QueryBuilder<DBMyFavoriteList>(DBMyFavoriteList.class);
                builder.where("listName = ?", url);

                ArrayList<DBMyFavoriteList> dbMyFavoriteLists = liteOrm.query(builder);
                handler.post(new HandlerRunnable(queryListener, dbMyFavoriteLists));
            }
        });
    }

    // 通过SongId查指定行
    public void queryDBMusicListBySongId(final String songId, final QueryListener queryListener) {
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                QueryBuilder<DBMusicList> builder = new QueryBuilder<DBMusicList>(DBMusicList.class);
                builder.where("songId = " + songId);
                ArrayList<DBMusicList> dbMusicLists = liteOrm.query(builder);
                handler.post(new HandlerRunnable(queryListener, dbMusicLists));
            }
        });
    }

    // 通过boolean 取最后播放的音乐
    public void querDBMusicListByBoolean(final QueryListener queryListener) {
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                QueryBuilder<DBMusicList> builder = new QueryBuilder<DBMusicList>(DBMusicList.class);
                builder.where("playing > 0");
                ArrayList<DBMusicList> dbMusicLists = liteOrm.query(builder);
                handler.post(new HandlerRunnable(queryListener, dbMusicLists));
            }
        });
    }

    // 储存收藏
    public void instertMyDBMusicList(final DBMyMusicList dbMyMusicList ) {

        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                liteOrm.insert(dbMyMusicList);

                DBMyMusicList dbMyMusicList1 = BmobUser.getCurrentUser(DBMyMusicList.class);
                if (dbMyMusicList1 != null&& !BmobUser.getCurrentUser().getUsername().equals("0")) {
                    if (dbMyMusicList != null) {
                        dbMyMusicList.save(new SaveListener<String>() {
                            @Override
                            public void done(String s, BmobException e) {
                                if (e == null) {
                                    Log.d("DBTool", "储存成功");
                                } else {
                                    Log.d("DBTool", e + "储存失败");
                                }
                            }
                        });
                        dbMyMusicList.setUsername(dbMyMusicList1.getUsername());
                    }
                } else {
                    Log.d("DBTool", "尚未登录");
                }
            }
        });
    }

    // 重载储存收藏 用于从云端拉取时 使用
    public void instertMyDBMusicList(final DBMyMusicList dbMyMusicList , int temp ) {

        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                liteOrm.insert(dbMyMusicList);
            }
        });
    }

    // 通过songId查收藏
    public void queryDBMyMusicList(final String songId, final QueryListener queryListener) {
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                QueryBuilder<DBMyMusicList> builder = new QueryBuilder<DBMyMusicList>(DBMyMusicList.class);
                builder.where("songId = " + songId);
                ArrayList<DBMyMusicList> dbMyMusicLists = liteOrm.query(builder);
                handler.post(new HandlerRunnable(queryListener, dbMyMusicLists));
            }
        });
    }

    // 写一个类作为handler的runnable
    class HandlerRunnable implements Runnable {
        List lists;
        QueryListener queryListener;

        //构造方法
        public <T> HandlerRunnable(QueryListener queryListener, List<T> lists) {
            this.queryListener = queryListener;
            this.lists = lists;
        }

        @Override
        public void run() {
            queryListener.onQueryListener(lists);

        }
    }

    //将查询数据回传的接口
    public interface QueryListener {
        <T> void onQueryListener(List<T> list);
    }

    private int getNumCores() {
        //Private Class to display only CPU devices in the directory listing
        class CpuFilter implements FileFilter {
            @Override
            public boolean accept(File pathname) {
                //Check if filename is "cpu", followed by a single digit number
                if(Pattern.matches("cpu[0-9]", pathname.getName())) {
                    return true;
                }
                return false;
            }
        }

        try {
            //Get directory containing CPU info
            File dir = new File("/sys/devices/system/cpu/");
            //Filter to only list the devices we care about
            File[] files = dir.listFiles(new CpuFilter());
            Log.d("dbTool", "CPU Count: "+files.length);
            //Return the number of cores (virtual CPU devices)
            return files.length;
        } catch(Exception e) {
            //Print exception
            Log.d("dbTool", "CPU Count: Failed.");
            e.printStackTrace();
            //Default to return 1 core
            return 1;
        }
    }



}
